Skip to content

Conversation

@podkidyshev
Copy link
Contributor

@podkidyshev podkidyshev commented Feb 11, 2026

Summary

Fix copyright and the related check according to the rule: copyright years must cover all but only the years when the file was changed.

Test Plan

Unit-tests are enough + verified a sample of affected files manually using gitlense vscode extension that shows commit history per file.

Additional Notes

A single file my change its path in the repo yet still stay interpreted as the same file in the history. The updated check covers this case

I have also tried to run constant number of git commands per session (O(1), not O(number of files)) but that doesn't cover the above-mentioned case.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 11, 2026

📝 Walkthrough

Walkthrough

This pull request updates copyright year ranges across approximately 45 configuration and source files throughout the codebase, and refactors the copyright header validation in the test suite with new helper functions for year formatting, git-based year tracking, and centralized header validation logic.

Changes

Cohort / File(s) Summary
Configuration copyright updates
conf/common/system/example_runai_cluster.toml, conf/common/test/dse_nccl_all_gather.toml, conf/common/test/nccl_test.toml, conf/common/test_scenario/..., conf/experimental/.../*
Updated copyright year ranges in file headers across configuration files to reflect correct year spans (2024-2026, 2025-2026, etc.). No functional changes.
Source module copyright updates
src/cloudai/_core/base_reporter.py, src/cloudai/configurator/..., src/cloudai/core.py, src/cloudai/models/scenario.py, src/cloudai/registration.py, src/cloudai/systems/lsf/..., src/cloudai/systems/runai/..., src/cloudai/workloads/.../*
Updated copyright year ranges in file headers across core and workload modules. No logic or API changes.
Test file copyright updates
tests/json_gen_strategy/..., tests/report_generation_strategy/..., tests/test_base_runner.py, tests/test_cli.py, tests/test_git_repo_installer.py
Updated copyright year ranges in test file headers. No functional changes.
Copyright header validation refactor
tests/test_check_copyright_headers.py
Introduced helper functions: _format_years_to_ranges() to convert year lists to compact ranges, get_commit_years_for_file() to extract commit years via git log with fallback to current year, prepare_copyright_with_year() to generate copyright lines, and _assert_copyright_in_file() to centralize header validation. Enhanced file status awareness to include current year for files with staged/unstaged changes.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 Copyright seasons come and go,
Years advancing through the code's new flow,
Headers updated, git logs combined,
Validation helpers, thoughtfully designed,
Two-thousand-twenty-four through six we go!

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Updated test to check for copyright' is directly related to the main changeset, which updates copyright year handling logic in the test file and applies copyright year corrections across multiple files.
Description check ✅ Passed The description clearly relates to the changeset, explaining the copyright year rule being implemented and tested, with references to handling moved files and manual verification.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ipod/copyright-verify

No actionable comments were generated in the recent review. 🎉


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In `@src/cloudai/workloads/ddlb/slurm_command_gen_strategy.py`:
- Line 2: The file header's copyright year range is inconsistent with other
files; update the top comment in slurm_command_gen_strategy.py to use the
standardized range (e.g., change "Copyright (c) 2024-2026" to the agreed range
used across the repo such as "2024-2026" or "2025-2026") so all updated files
share the same copyright years; locate the header comment at the top of the file
and replace the existing year range text accordingly to match the standard used
across the project.

In `@tests/test_check_copyright_headers.py`:
- Line 47: CURRENT_YEAR is evaluated at import time which can cause failures
across a year boundary; move the computation into get_commit_years_for_file so
the year is calculated at call time. Update get_commit_years_for_file to compute
current_year = datetime.now().year (or use datetime.utcnow() if needed for
timezone consistency) and use that local variable instead of the module-level
CURRENT_YEAR constant; remove or deprecate the top-level CURRENT_YEAR to avoid
stale values.
- Around line 76-86: Add a negative test that verifies
_format_years_to_ranges([]) raises the expected ValueError: create a new test
function (e.g., test_format_years_to_ranges_empty_raises) that calls
_format_years_to_ranges with an empty list and uses pytest.raises(ValueError,
match="Expected at least one year") to assert the error and message; place it
alongside the existing tests in tests/test_check_copyright_headers.py.
- Around line 127-141: Update the assertions in _assert_copyright_in_file to
include actual vs expected values and file context to improve debuggability: for
the SPDX check (actual_copyright_lines[0]), the years check
(actual_copyright_lines[1] vs expected_years_line) and the tail check
("\n".join(actual_copyright_lines[2:]) vs HEADER_TAIL) include the file name
plus both expected and actual values in each assertion message; reference the
variables actual_copyright_lines, expected_years_line, HEADER_TAIL and
HEADER_LINES so the failure output clearly shows what was expected and what was
received.
- Around line 96-106: The git subprocess invocations that populate `res` (the
two subprocess.run calls using ["git", "log", ...] and any other git
subprocess.run calls like git status) lack return-code checks and can fail
silently; update these calls to either use check=True or inspect
`res.returncode` and throw a descriptive exception (or raise
subprocess.CalledProcessError) including `res.stderr` and the command arguments
when non-zero, so the test fails with a clear error instead of returning an
incorrect year value; ensure you update all occurrences around the
`res`/`path_str` usage (the git log/status subprocess.run calls) accordingly.

Comment on lines +76 to +86
@pytest.mark.parametrize(
("years_list", "expected"),
(
([2024, 2026], "2024, 2026"),
([2024, 2025, 2027], "2024-2025, 2027"),
([2024], "2024"),
([2024, 2025, 2026], "2024-2026"),
),
)
def test_format_years_to_ranges(years_list: list[int], expected: str):
assert _format_years_to_ranges(years_list) == expected
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider adding a test for the empty list case.

The function raises ValueError for an empty input list (lines 56-60), but there's no test case verifying this behavior. Adding a test ensures the error handling remains intact.

💡 Suggested test case
def test_format_years_to_ranges_empty_raises():
    with pytest.raises(ValueError, match="Expected at least one year"):
        _format_years_to_ranges([])
🤖 Prompt for AI Agents
In `@tests/test_check_copyright_headers.py` around lines 76 - 86, Add a negative
test that verifies _format_years_to_ranges([]) raises the expected ValueError:
create a new test function (e.g., test_format_years_to_ranges_empty_raises) that
calls _format_years_to_ranges with an empty list and uses
pytest.raises(ValueError, match="Expected at least one year") to assert the
error and message; place it alongside the existing tests in
tests/test_check_copyright_headers.py.

Comment on lines 96 to 106
res = subprocess.run(
["git", "log", "--format=%ad", "--date=format:%Y", "--follow", "-1", file],
["git", "log", "--format=%ad", "--date=format:%Y", "--follow", "--", path_str],
capture_output=True,
text=True,
)
if not res.stdout:
# in some cases when a file was renamed, --follow won't allow getting the last modified year
if not res.stdout.strip():
res = subprocess.run(
["git", "log", "--format=%ad", "--date=format:%Y", "-1", file],
["git", "log", "--format=%ad", "--date=format:%Y", "--", path_str],
capture_output=True,
text=True,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Missing error handling for git subprocess calls.

The function doesn't check returncode from the subprocess calls. If git log or git status fails (e.g., not a git repo, corrupted repo, git not installed), the function may silently return incorrect results like [CURRENT_YEAR] instead of raising an informative error.

🛡️ Suggested fix to add error checking
     res = subprocess.run(
         ["git", "log", "--format=%ad", "--date=format:%Y", "--follow", "--", path_str],
         capture_output=True,
         text=True,
     )
+    if res.returncode != 0 and res.returncode != 128:  # 128 = no commits match
+        raise RuntimeError(f"git log failed for {path_str}: {res.stderr}")
     if not res.stdout.strip():
         res = subprocess.run(
             ["git", "log", "--format=%ad", "--date=format:%Y", "--", path_str],
             capture_output=True,
             text=True,
         )
+        if res.returncode != 0 and res.returncode != 128:
+            raise RuntimeError(f"git log failed for {path_str}: {res.stderr}")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
res = subprocess.run(
["git", "log", "--format=%ad", "--date=format:%Y", "--follow", "-1", file],
["git", "log", "--format=%ad", "--date=format:%Y", "--follow", "--", path_str],
capture_output=True,
text=True,
)
if not res.stdout:
# in some cases when a file was renamed, --follow won't allow getting the last modified year
if not res.stdout.strip():
res = subprocess.run(
["git", "log", "--format=%ad", "--date=format:%Y", "-1", file],
["git", "log", "--format=%ad", "--date=format:%Y", "--", path_str],
capture_output=True,
text=True,
)
res = subprocess.run(
["git", "log", "--format=%ad", "--date=format:%Y", "--follow", "--", path_str],
capture_output=True,
text=True,
)
if res.returncode != 0 and res.returncode != 128: # 128 = no commits match
raise RuntimeError(f"git log failed for {path_str}: {res.stderr}")
if not res.stdout.strip():
res = subprocess.run(
["git", "log", "--format=%ad", "--date=format:%Y", "--", path_str],
capture_output=True,
text=True,
)
if res.returncode != 0 and res.returncode != 128:
raise RuntimeError(f"git log failed for {path_str}: {res.stderr}")
🤖 Prompt for AI Agents
In `@tests/test_check_copyright_headers.py` around lines 96 - 106, The git
subprocess invocations that populate `res` (the two subprocess.run calls using
["git", "log", ...] and any other git subprocess.run calls like git status) lack
return-code checks and can fail silently; update these calls to either use
check=True or inspect `res.returncode` and throw a descriptive exception (or
raise subprocess.CalledProcessError) including `res.stderr` and the command
arguments when non-zero, so the test fails with a clear error instead of
returning an incorrect year value; ensure you update all occurrences around the
`res`/`path_str` usage (the git log/status subprocess.run calls) accordingly.

@podkidyshev podkidyshev self-assigned this Feb 12, 2026
@podkidyshev podkidyshev marked this pull request as ready for review February 12, 2026 13:59
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 12, 2026

Greptile Overview

Greptile Summary

This PR updates copyright headers across 52 files to accurately reflect the years when files were modified, based on git commit history. The main improvement is in tests/test_check_copyright_headers.py, which now:

  • Uses git log --follow to track file history even through renames/moves
  • Collects all years when a file was changed and formats consecutive years as ranges (e.g., 2024-2026)
  • Includes the current year for new or uncommitted files
  • Adds comprehensive unit tests for the year formatting logic

Key improvements:

  • Handles file renames correctly using --follow flag
  • Formats year ranges properly (consecutive years like 2024, 2025, 2026 become "2024-2026")
  • Checks git status to include current year for modified files
  • Better error handling with return code checks (128 for no commits)
  • Automated copyright year validation based on actual git history

Confidence Score: 5/5

  • This PR is safe to merge with no risks
  • The PR implements a systematic copyright year verification system that automatically validates copyright headers against git history. All 52 files have been updated with correct copyright years based on actual commit history, verified through sampling. The test logic is well-structured with proper error handling and comprehensive unit tests.
  • No files require special attention

Important Files Changed

Filename Overview
tests/test_check_copyright_headers.py Improved copyright year checking logic to use git history with --follow flag to handle file renames/moves, and format consecutive years as ranges
src/cloudai/core.py Updated copyright years from 2024-2025 to 2025-2026 based on git commit history
src/cloudai/registration.py Updated copyright years from 2024-2026 to 2025-2026 based on git commit history
conf/common/system/example_runai_cluster.toml Updated copyright year to match actual git commit history

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

52 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

@podkidyshev podkidyshev marked this pull request as draft February 12, 2026 16:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant